#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2025 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import logging
import re
import json
import os
from utils import utils_data, ErrorInfoBuilder


def is_pascal_case(filename):
    pattern = re.compile(r'^[A-Z][a-zA-Z0-9]*$')
    base_name = os.path.splitext(filename)[0]
    return bool(pattern.match(base_name))


def check_c_naming(file_name):
    base_name = file_name[:-2]
    return file_name.endswith('test.c') and re.match(r'^[a-z]+(_[a-z]+)*$', base_name)


def check_js_ets_naming(file_name):
    if file_name.endswith('.js'):
        base_name = file_name[:-3]
        correct_suffix = '.test.js'
    else:
        base_name = file_name[:-4]
        correct_suffix = '.test.ets'
    return file_name.endswith(correct_suffix) and is_pascal_case(base_name)


def check_test_filename():
    logger = logging.getLogger('my_logger')
    file_entities = utils_data.get_file()
    has_error = False

    for entity in file_entities:
        file_name = entity.file_name
        relative_path = entity.file_path
        language = "arkts" if file_name.endswith('.ets') else "javascript"

        if file_name.endswith('.cpp'):
            base_name = file_name[:-4]
            if not file_name.endswith('Test.cpp') or not is_pascal_case(base_name):
                error_info = ErrorInfoBuilder() \
                    .set_buggy_file_path(relative_path) \
                    .set_defect_type("XTS.CHECK.TESTFILENAME.01") \
                    .set_description(
                    "c++测试源码文件不符合规范，应采用大驼峰命名风格，不能有下划线且需以Test.cpp 结尾") \
                    .set_main_buggy_line(0) \
                    .set_main_buggy_code(file_name) \
                    .set_language("c++") \
                    .build()
                utils_data.write_error_to_json_file(error_info)
                logger.info(json.dumps(error_info, indent=4, ensure_ascii=False))
                has_error = True

        elif file_name.endswith('.c'):
            if not check_c_naming(file_name):
                error_info = ErrorInfoBuilder() \
                    .set_buggy_file_path(relative_path) \
                    .set_defect_type("XTS.CHECK.TESTFILENAME.01") \
                    .set_description("c测试源码文件命名不符合规范，应采用单词间用 _ 分隔的命名风格且以test.c 结尾") \
                    .set_main_buggy_line(0) \
                    .set_main_buggy_code(file_name) \
                    .set_language("c") \
                    .build()
                utils_data.write_error_to_json_file(error_info)
                logger.info(json.dumps(error_info, indent=4, ensure_ascii=False))
                has_error = True

        elif file_name.endswith('.js') or file_name.endswith('.ets'):
            dirname = os.path.dirname(relative_path)
            if not os.path.basename(dirname) == 'test':
                continue
            if not check_js_ets_naming(file_name):
                description = "js测试源码文件命名不符合规范，应采用大驼峰命名风格，不能有下划线且需以.test.js 结尾" if file_name.endswith(
                    '.js') else "ets测试源码文件命名不符合规范，应采用大驼峰命名风格，不能有下划线且需以.test.ets 结尾"
                error_info = ErrorInfoBuilder() \
                    .set_buggy_file_path(relative_path) \
                    .set_defect_type("XTS.CHECK.TESTFILENAME.01") \
                    .set_description(description) \
                    .set_main_buggy_line(0) \
                    .set_main_buggy_code(file_name) \
                    .set_language(language) \
                    .build()
                utils_data.write_error_to_json_file(error_info)
                logger.info(json.dumps(error_info, indent=4, ensure_ascii=False))
                has_error = True

    if has_error:
        logger.info("测试源码文件命名规范检查完成，错误信息已写入xts_result.json")
    else:
        logger.info("测试源码文件命名规范检查通过")
